/*
 * This file is part of LangMan.
 *
 * LangMan is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * LangMan is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LangMan.  If not, see <http://www.gnu.org/licenses/>.
 */

package langman;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import langman.business.data.TranslationException;
import langman.business.profiles.Profile;
import langman.business.profiles.ProfileService;
import langman.gui.MainFrame;
import langman.gui.StageService;
import langman.gui.profile.ProfileControl;
import langman.util.async.TaskExecutorService;
import langman.util.doping.Context;
import langman.util.guifactory.GUIFactory;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.controlsfx.dialog.Dialogs;

public class LangMan extends Application {

    public static void main(String... args) {
        Application.launch(LangMan.class, args);
    }

    private final Logger logger = LogManager.getRootLogger();

    @Override
    public void start(Stage primaryStage) throws Exception {

        EventHandler<WindowEvent> applicationKillerHandler = event -> {
            //noinspection CallToSystemExit
            System.exit(0);
        };
        primaryStage.setOnHidden(applicationKillerHandler);
        primaryStage.setOnCloseRequest(applicationKillerHandler);
        
        Logger logger = LogManager.getRootLogger();
        org.apache.logging.log4j.core.Logger coreLogger
                = (org.apache.logging.log4j.core.Logger) logger;
        coreLogger.addAppender(new ExitApplicationAppender());

        Context context = new Context("com.thekey.translation");

        ProfileService profileService = context.getBean(ProfileService.class);

        GUIFactory guiFactory = context.getBean(GUIFactory.class);

        ProfileControl profileControl = guiFactory.createControl(ProfileControl.class);
        Profile profile = profileControl.showAndWait();

        if (profileControl.isExitedWithoutOK()) {
            Platform.exit();
            return;
        }

        if (profile == null) {
            exitWithError(new TranslationException("No profile chosen!"));
            return;
        }
        profileService.setSelectedProfile(profile);

        StageService stageService = context.getBean(StageService.class);
        stageService.setMainStage(primaryStage);

        MainFrame mainFrame = guiFactory.createControl(MainFrame.class);

        primaryStage.setScene(new Scene(mainFrame.getNode()));
        primaryStage.setTitle("Language Manager");
        primaryStage.toFront();
        primaryStage.show();

        TaskExecutorService taskExecutorService = context.getBean(TaskExecutorService.class);
        AppInitializationTask appInitializationTask = context.getBean(AppInitializationTask.class);
        taskExecutorService.execute("Loading languages", appInitializationTask);
    }

    private void exitWithError(Throwable error) {
        logger.error(error.getMessage(), error);
    }

    private static class ExitApplicationAppender extends AbstractAppender {
        protected ExitApplicationAppender() {
            super("Exit Application Appender", null, null);
        }

        @Override
        public void append(LogEvent logEvent) {
            if (logEvent.getLevel().isAtLeastAsSpecificAs(Level.ERROR)) {
                String message = logEvent.getMessage().getFormattedMessage();
                Dialogs.create().message("A fatal error has occured, language consistency can not be guaranteed, therefore application will now exit! Reason: " + message).showError();
                Platform.exit();
            }
        }
    }
}
